package org.intrasearch.core;

import com.google.common.collect.ImmutableSet;
import com.google.inject.Singleton;
import org.intrasearch.core.collections.BigMap;
import org.intrasearch.core.io.ImmutableSetExternalizableProvider;
import org.intrasearch.core.io.SerializationBuilder;
import org.intrasearch.core.io.SerializationConfig;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Singleton
public class ArtifactStorageImpl implements ArtifactStorage
{
    private final Map<ArtifactId, Artifact> artifacts;

    public ArtifactStorageImpl()
    {
        try
        {
            artifacts = new BigMap<ArtifactId, Artifact>(File.createTempFile("ArtifactStorage","index"), (int) Math.pow(2,24), new SerializationConfig()
            {
                public void configure(SerializationBuilder builder)
                {
                    builder.addClass(ArtifactId.class);
                    builder.addClass(FileArtifactImpl.class);
                    builder.addClass(DirectoryArtifactImpl.class);
                    builder.addExternalizableProvider(ImmutableSet.class, new ImmutableSetExternalizableProvider());
                }
            });
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    ArtifactStorageImpl(Map<ArtifactId, Artifact> artifacts)
    {
        this.artifacts = artifacts;
    }

    public List<Artifact> artifactsByIds(List<ArtifactId> artifactIds)
    {
        List<Artifact> artifactArrayList = new ArrayList<Artifact>();
        for (ArtifactId artifactId : artifactIds)
        {
            artifactArrayList.add(artifacts.get(artifactId));
        }
        return artifactArrayList; 
    }

    public void addArtifact(Artifact artifact)
    {
        Artifact oldArtifact = artifacts.remove(artifact.getArtifactId());
        artifacts.put(artifact.getArtifactId(), oldArtifact != null ? oldArtifact.merge(artifact) : artifact);
    }

    public void flush()
    {
        if (!(artifacts instanceof BigMap))
        {
            return;
        }
        BigMap bigMap = (BigMap) artifacts;
        bigMap.flush();
    }
}
